package com.zzyl.nursing.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.json.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zzyl.common.exception.base.BaseException;
import com.zzyl.common.utils.ThreadLocalUtil;
import com.zzyl.nursing.domain.DeviceData;
import com.zzyl.nursing.domain.Elder;
import com.zzyl.nursing.domain.FamilyMemberElder;
import com.zzyl.nursing.dto.FamilyMemberElderDto;
import com.zzyl.nursing.mapper.DeviceDataMapper;
import com.zzyl.nursing.mapper.ElderMapper;
import com.zzyl.nursing.mapper.FamilyMemberElderMapper;
import com.zzyl.nursing.mapper.FamilyMemberMapper;
import com.zzyl.nursing.service.IFamilyMemberElderService;
import com.zzyl.nursing.vo.FamilyMemberPageVo;
import com.zzyl.nursing.vo.MyElderVo;
import com.zzyl.nursing.vo.ServicePropertyVo;
import com.zzyl.nursing.vo.PropertyStatusListVo;
import com.zzyl.nursing.vo.PropertyStatusInfoVo;
import com.zzyl.nursing.dto.QueryDevicePropertyStatusDto;
import com.zzyl.common.constant.CacheConstants;
import cn.hutool.json.JSONUtil;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;

@Service
public class IFamilyMemberElderServiceImpl extends ServiceImpl<FamilyMemberElderMapper, FamilyMemberElder> implements IFamilyMemberElderService {
    @Autowired
    private ElderMapper elderMapper;

    @Autowired
    private FamilyMemberElderMapper familyMemberElderMapper;

    @Autowired
    private FamilyMemberMapper familyMemberMapper;

    @Autowired
    private DeviceDataMapper deviceDataMapper;
    
    @Autowired
    private RedisTemplate<String, String> redisTemplate;
    
    @Override
    public void bindElder(FamilyMemberElderDto dto) {
        Elder elder1;
        Elder elder = elderMapper.selectOne(
                new LambdaQueryWrapper<Elder>()
                        .eq(Elder::getIdCardNo,dto.getIdCard())
        );
        if(elder==null){
            throw new BaseException("老人不存在！");
        }
        boolean exists = this.lambdaQuery()
                .eq(FamilyMemberElder::getFamilyMemberId, ThreadLocalUtil.get())
                .eq(FamilyMemberElder::getElderId, elder.getId())
                .exists();

        if (exists) {
            throw new RuntimeException("该老人已绑定");
        }
        FamilyMemberElder relation = new FamilyMemberElder();
        relation.setFamilyMemberId(ThreadLocalUtil.get());
        relation.setElderId(elder.getId());
        relation.setRemark(dto.getRemark());
        familyMemberElderMapper.insert(relation);
    }

    @Override
    public List<MyElderVo> selectMyElderList() {
        Long familyMemberId = ThreadLocalUtil.get();
        if (familyMemberId == null) {
            throw new BaseException("用户未登录");
        }
        return familyMemberElderMapper.selectMyElderList(familyMemberId);
    }

    @Override
    public List<FamilyMemberPageVo> selectFamilyMemberListByPage() {
        Long familyMemberId = ThreadLocalUtil.get();
        if (familyMemberId == null) {
            throw new BaseException("用户未登录");
        }
        return familyMemberElderMapper.selectFamilyMemberListByPage(familyMemberId);
    }

    /**
     * 查询健康数据（新版）
     *
     * @param iotId 设备ID
     * @return 服务属性列表
     */
    @Override
    public List<ServicePropertyVo> queryServiceProperties(String iotId)
    {
        List<ServicePropertyVo> result = new ArrayList<>();

        // 从Redis缓存中查询设备的最新数据
        String cacheKey = CacheConstants.IOT_DEVICE_LAST_DATA;
        System.out.println("查询Redis缓存，key: " + cacheKey);


        Object values = redisTemplate.opsForHash().get(cacheKey, iotId);
        if (values != null) {
            List<DeviceData> list = JSONUtil.toList(values.toString(), DeviceData.class);
            list.forEach(v -> {
                if (v.getFunctionId().equals("HeartRate")) {
                    ServicePropertyVo heartRateVo = new ServicePropertyVo();
                    heartRateVo.setFunctionId("HeartRate");
                    heartRateVo.setEventTime(v.getAlarmTime().format(DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss")));
                    heartRateVo.setValue(v.getDataValue());
                    result.add(heartRateVo);
                }
            });
        }
        return result;
    }

    /**
     * 生成模拟健康数据（用于测试）
     *
     * @param iotId 设备ID
     */
    private void generateMockData(String iotId)
    {
        // 心率数据
        DeviceData heartRateData = new DeviceData();
        heartRateData.setIotId(iotId);
        heartRateData.setFunctionId("HeartRate");
        heartRateData.setDataValue(String.valueOf(60 + (int)(Math.random() * 20))); // 60-80
        heartRateData.setAlarmTime(java.time.LocalDateTime.now());
        deviceDataMapper.insertDeviceData(heartRateData);

        // 存储到Redis缓存
        String cacheKey = CacheConstants.IOT_DEVICE_LAST_DATA + iotId;
        redisTemplate.opsForValue().set(cacheKey, JSONUtil.toJsonStr(heartRateData));

        // 上床时间数据
        DeviceData bedTimeData = new DeviceData();
        bedTimeData.setIotId(iotId);
        bedTimeData.setFunctionId("BedTime");
        bedTimeData.setDataValue(String.valueOf(System.currentTimeMillis()));
        bedTimeData.setAlarmTime(java.time.LocalDateTime.now());
        deviceDataMapper.insertDeviceData(bedTimeData);

        // 睡眠阶段状态数据
        DeviceData sleepPhaseData = new DeviceData();
        sleepPhaseData.setIotId(iotId);
        sleepPhaseData.setFunctionId("SleepPhaseState");
        sleepPhaseData.setDataValue(String.valueOf(1 + (int)(Math.random() * 3))); // 1-3
        sleepPhaseData.setAlarmTime(java.time.LocalDateTime.now());
        deviceDataMapper.insertDeviceData(sleepPhaseData);

        // 呼吸率数据
        DeviceData respiratoryData = new DeviceData();
        respiratoryData.setIotId(iotId);
        respiratoryData.setFunctionId("RespiratoryRate");
        respiratoryData.setDataValue(String.valueOf(70 + (int)(Math.random() * 20))); // 70-90
        respiratoryData.setAlarmTime(java.time.LocalDateTime.now());
        deviceDataMapper.insertDeviceData(respiratoryData);

        // 离床次数数据
        DeviceData bedExitData = new DeviceData();
        bedExitData.setIotId(iotId);
        bedExitData.setFunctionId("BedExitCount");
        bedExitData.setDataValue(String.valueOf((int)(Math.random() * 5))); // 0-4
        bedExitData.setAlarmTime(java.time.LocalDateTime.now());
        deviceDataMapper.insertDeviceData(bedExitData);
    }

    @Override
    public PropertyStatusListVo queryDevicePropertyStatus(QueryDevicePropertyStatusDto dto)
    {
        PropertyStatusListVo result = new PropertyStatusListVo();
        List<PropertyStatusInfoVo> propertyStatusInfoList = new ArrayList<>();

        // 从Redis缓存中查询设备的最新数据
        // 使用设备名称作为iotId来查询Redis
        String cacheKey = CacheConstants.IOT_DEVICE_LAST_DATA + dto.getDeviceName();
        System.out.println("查询Redis缓存，key: " + cacheKey);
        
        // 先检查Redis中所有相关的key
        Set<String> keys = redisTemplate.keys(CacheConstants.IOT_DEVICE_LAST_DATA + "*");
        System.out.println("Redis中所有设备数据key: " + keys);
        
        Object cacheData = redisTemplate.opsForValue().get(cacheKey);
        System.out.println("Redis缓存数据: " + cacheData);
        
        if (cacheData != null) {
            // 解析缓存中的设备数据
            DeviceData deviceData = JSONUtil.toBean(cacheData.toString(), DeviceData.class);
            
            if (deviceData != null) {
                // 心率数据 - 从Redis获取真实数据
                PropertyStatusInfoVo heartRate = new PropertyStatusInfoVo();
                heartRate.setDataType("int");
                heartRate.setIdentifier("HeartRate");
                heartRate.setName("心率");
                heartRate.setTime(String.valueOf(System.currentTimeMillis()));
                heartRate.setUnit("");
                heartRate.setValue(deviceData.getDataValue());
                propertyStatusInfoList.add(heartRate);
            }
        }

        // 其他模拟数据
        // 体温数据
        PropertyStatusInfoVo bodyTemp = new PropertyStatusInfoVo();
        bodyTemp.setDataType("float");
        bodyTemp.setIdentifier("BodyTemp");
        bodyTemp.setName("体温");
        bodyTemp.setTime(String.valueOf(System.currentTimeMillis()));
        bodyTemp.setUnit("℃");
        bodyTemp.setValue(String.valueOf(36.5 + Math.random() * 2.5)); // 36.5-39.0
        propertyStatusInfoList.add(bodyTemp);

        // 血氧数据
        PropertyStatusInfoVo xueyang = new PropertyStatusInfoVo();
        xueyang.setDataType("int");
        xueyang.setIdentifier("xueyang");
        xueyang.setName("血氧");
        xueyang.setTime(String.valueOf(System.currentTimeMillis()));
        xueyang.setUnit("");
        xueyang.setValue(String.valueOf(95 + (int)(Math.random() * 15))); // 95-110
        propertyStatusInfoList.add(xueyang);

        // 电池电量数据
        PropertyStatusInfoVo battery = new PropertyStatusInfoVo();
        battery.setDataType("double");
        battery.setIdentifier("BatteryPercentage");
        battery.setName("电池电量百分比");
        battery.setTime(String.valueOf(System.currentTimeMillis()));
        battery.setUnit("%");
        battery.setValue(String.valueOf(-22.0 + Math.random() * 100)); // -22.0到78.0
        propertyStatusInfoList.add(battery);

        // 血压数据
        PropertyStatusInfoVo xueya = new PropertyStatusInfoVo();
        xueya.setDataType("int");
        xueya.setIdentifier("xueya");
        xueya.setName("血压");
        xueya.setTime(String.valueOf(System.currentTimeMillis()));
        xueya.setUnit("");
        xueya.setValue(String.valueOf(90 + (int)(Math.random() * 40))); // 90-130
        propertyStatusInfoList.add(xueya);

        result.setPropertyStatusInfo(propertyStatusInfoList);
        return result;
    }

    /**
     * 删除
     * @param id
     */
    @Override
    public void deleteById(Long id) {
        familyMemberElderMapper.deleteById(id);
    }
}
